package com.funtl.spring.cloud.alibaba.unit.controller;

import com.funtl.spring.cloud.alibaba.unit.domain.Movie;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @ClassName MovieController
 * @Description TODO
 * @Author Mr.Starry
 * @Date 2019/12/30 22:25
 * @Version 1.0
 */
@RequestMapping
@RestController
public class MovieController {
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    /*
     {
       "query": {
         "match": {
           "title": "beautiful"
          }
        }
       "from": 0,
       "size": 10,
       "sorted": {
         "year": {
            "order": "desc"
          }
         }
       }
     }
     分页默认是从0开始的
     */
    @RequestMapping("/match")
    public Object match(String text,
                        @RequestParam(required = false, defaultValue = "0") Integer page,
                        @RequestParam(required = false, defaultValue = "10") Integer size) {

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(new MatchQueryBuilder("genre", text))
                .withPageable(PageRequest.of(page, size))  //分页
                .withSort(new FieldSortBuilder("year").order(SortOrder.DESC))  //按照年份的倒序排序
                .build();

        List<Movie> list = elasticsearchTemplate.queryForList(searchQuery, Movie.class);
        return list;
    }


    /*
       GET movies/_search
        {
          "query": {
            "match_phrase": {
              "title": "Beautiful Mind"
            }
          }
        }
     */
    @RequestMapping("/match-phrase")
    public Object matchPhrase(String text) {
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(new MatchPhraseQueryBuilder("title", text))
                .build();

        List<Movie> list = elasticsearchTemplate.queryForList(searchQuery, Movie.class);
        return list;
    }

    /*
      GET movies/_search
        {
          "query": {
            "bool": {
              "must": [
                {
                  "range": {
                    "year": {
                      "gte": 2016,
                      "lte": 2018
                    }
                  }
                },
                {
                  "match": {
                    "title": "Beautiful Mind"
                  }
                }
              ]
            }
          }
        }
     */
    // spring data
    @RequestMapping("/bool")
    public Object bool() {
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withSourceFilter(new FetchSourceFilter(new String[]{"year", "title"}, new String[]{}))
                .withQuery(
                        new BoolQueryBuilder().must(new MatchQueryBuilder("title", "beautiful mind"))
                                .must(new RangeQueryBuilder("year").gte(1990).lte(2018))
                ).build();

        List<Movie> list = elasticsearchTemplate.queryForList(searchQuery, Movie.class);
        return list;
    }


    /*
      {
          "query": {
            "multi_match": {
              "query": "beautiful mind Romance",
              "fields": ["title", "genre"],
              "type": "best_fields"
            }
          }
        }
     */
    @RequestMapping("/multi-match")
    public Object multi_match(String text) {
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(
                        new MultiMatchQueryBuilder(text, "genre", "title")
                                .type(MultiMatchQueryBuilder.Type.BEST_FIELDS))
                .build();

        List<Movie> list = elasticsearchTemplate.queryForList(searchQuery, Movie.class);
        return list;
    }
}
